package com.zcxy.fast.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.zcxy.fast.bean.SysUser;
import com.zcxy.fast.constant.CommonConstant;
import com.zcxy.fast.exception.BusinessException;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * @Author
 * @Date 2018-07-12 14:23
 * @Desc JWT工具类
 **/
public class JwtUtil {

    // 过期时间30分钟
    public static final long EXPIRE_TIME = 30 * 60 * 1000;


    public static final  String SECRET="token";


    public static boolean verify(String token, String username, String secret, String lang) {
        try {
            // 根据密码生成JWT效验器
            Algorithm algorithm = Algorithm.HMAC256(secret);
            JWTVerifier verifier =
                    JWT.require(algorithm).withClaim("loginName", username).withClaim("lang", lang).build();
            // 效验TOKEN
            DecodedJWT jwt = verifier.verify(token);
            return true;
        } catch (Exception exception) {
            return false;
        }
    }

    /**
     * 获得token中的信息无需secret解密也能获得
     *
     * @return token中包含的用户名
     */
    public static String getKeyValue(String token, String key) {
        try {
            //如果以那个Bearer
            if (token != null && !StringUtils.isEmpty(token) && token.startsWith("Bearer")) {
                token = token.substring(6);
            }
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim(key).asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 生成签名,5min后过期
     *
     * @param username 用户名
     * @param secret   用户的密码
     * @return 加密的token
     */
    public static String sign(String username, String secret) {
        Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
        Algorithm algorithm = Algorithm.HMAC256(secret);
        // 附带username信息
        JWTCreator.Builder builder = JWT.create();
        builder.withClaim("loginName", username);

        builder.withExpiresAt(date);
        String signStr = builder.sign(algorithm);
        return signStr;

    }


    public static String createTokenByUser(SysUser sysUser, String secret) {
        Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
        Algorithm algorithm = Algorithm.HMAC256(secret);
        // 附带username信息
        JWTCreator.Builder builder = JWT.create();
        builder.withClaim("loginName", sysUser.getLoginName());
        builder.withClaim("userId", sysUser.getId() + "");
        builder.withClaim("userName", sysUser.getUserName() + "");
        builder.withExpiresAt(date);
        String signStr = builder.sign(algorithm);
        return signStr;

    }

    public static SysUser getLoginUser() {
        SysUser sysUser = new SysUser();
        try {
            String token = JwtUtil.getKVByHeadr(CommonConstant.X_ACCESS_TOKEN);
            sysUser.setLoginName(JwtUtil.getKeyValue(token, "loginName"));
            sysUser.setId(JwtUtil.getKeyValue(token, "userId"));
            sysUser.setUserName(JwtUtil.getKeyValue(token, "userName"));
        } catch (Exception e) {
            sysUser.setLoginName("admin");
        }
        return sysUser;
    }


    /**
     * 根据request中的key获取value
     *
     * @param name
     * @return
     * @throws
     */
    public static String getKVByHeadr(String name) {
        HttpServletRequest request =
                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String value = request.getHeader(name);
        return value;
    }


    public static void main(String[] args) {
        String a = "Bearer 9876";
        System.out.println(a.substring(6));
    }

    /**
     * 根据request中的token获取客户环境
     *
     * @param key
     * @return
     * @throws Math
     */
    public static String getKVByToken(String key) throws BusinessException {
        if (null == RequestContextHolder.getRequestAttributes()) {
            return null;
        }
        HttpServletRequest request =
                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        if ("lang".equals(key)) {
            String lang = request.getHeader(CommonConstant.X_ACCESS_LANG);
            if (StringUtils.isEmpty(lang)) {
                String accessToken = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
                if (StringUtils.isEmpty(accessToken)) {
                    return CommonConstant.ZH_LANG;
                }
                String value = getKeyValue(accessToken, key);
                if (StringUtils.isEmpty(value)) {
                    value = CommonConstant.ZH_LANG;
                }
                return value;
            } else {
                return CommonConstant.ZH_LANG;
            }
        } else {
            String accessToken = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
            if (StringUtils.isEmpty(accessToken)) {
                return null;
            }
            String value = getKeyValue(accessToken, key);
            return value;
        }

    }
}
